#include "gpt.h"

// 初始化GPT定时器
void GPT1_Init(void)
{
    // 1. GPTx_CR寄存器清0
    GPT1->CR = 0x00000000;

    // 2. 复位GPT定时器
    GPT1->CR |= (0x1<<15);
    while(((GPT1->CR)>>15) & 0x1);// 等待复位结束

    // 3. GPT模块重新使能时,计数器从0开始
    GPT1->CR |= (0x1<<1);

    // 4. 配置GPT1模块的时钟源为IPG_CLK
    GPT1->CR |= (0x1<<6);

    // 5. 配置计数器模式为重启模式
    GPT1->CR &= ~(0x1<<9);

    // 6. 输出比较通道1的模式控制位默认为0;

    // 7. 设置分频值为65,则分频系数为66(1us计数器累加1)
    GPT1->PR = 0x41;
    
    // 8. 通过读取GPTx_CNT寄存器的值实现延迟, 当前为1us计数器累加1
    // 设置GPT1_OCR1寄存器的值为0xFFFFFFFF,一轮为0xFFFFFFFF=71.5min
    GPT1->OCR[0]=0xFFFFFFFF;

    //GPT1->OCR[0]= 500000;


    // 8. 设置输出比较寄存器1的预设比较值(500ms)
    //GPT1->OCR[0]= 500000;

    // 9. 输出比较通道 1 中断使能
    // GPT1->IR |= (0x1<<0);
    
    // // 10. 使能GIC
    // GIC_EnableIRQ(GPT1_IRQn);

    // // 11. 注册中断服务函数
    // BindIRQTable(GPT1_IRQn, GPT1_IRQHandler,NULL);

    // 12. 启用GPT1模块的计数器
    GPT1->CR |= (0x1<<0);
}


#if 0
void GPT1_IRQHandler(unsigned int id, void* para)
{
    static unsigned char state = 1;
    //由于中断号GPT1_IRQn为GPT溢出中断,2个输入捕获中断,3个输出比较中断共用
    //所以首先应该判断是否发生了输出比较通道1中断
    if((GPT1->SR) & 0x1)
    {
        state = !state ;
        Led_Toggle(state);
    }

    // 清除中断标志位
    GPT1->SR |= (0x1<<0);
}
#endif

void DelayUs(unsigned int value)
{
    volatile unsigned int prev = 0;
    volatile unsigned int cur = 0;
    volatile unsigned int curvalue=0;
    // 1. 读取GPTx_CNT寄存器的值
    prev=GPT1->CNT;

    // 2. 判断GPTx_CNT的值是否累加到value+prev
    while(1)
    {
        cur=GPT1->CNT;

        // GPT定时器溢出
        if(cur < prev)
        {
            curvalue += ((0xFFFFFFFF-prev)+cur);
        }
        // GPT定时器未溢出
        else
        {
            curvalue += cur-prev;
        }
        prev=cur;
        if(curvalue >= value)
            break;
    }
}

void DelayMs(unsigned int value)
{
    unsigned int i=0;
    for(i=0;i<value;i++)
    {
        DelayUs(1000);
    }
}


